package com.lcy.reggie.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lcy.reggie.common.Result;
import com.lcy.reggie.dto.DishDto;
import com.lcy.reggie.entity.Category;
import com.lcy.reggie.entity.Dish;
import com.lcy.reggie.entity.DishFlavor;
import com.lcy.reggie.service.CategoryService;
import com.lcy.reggie.service.DishFlavorService;
import com.lcy.reggie.service.DishService;
import com.lcy.reggie.mapper.DishMapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author ChunBaBa_
 * @description 针对表【dish(菜品管理)】的数据库操作Service实现
 * @createDate 2023-01-17 13:59:03
 */
@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish>
        implements DishService {

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private CategoryService categoryService;

    /**
     * 菜品分页查询
     *
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public Result<Page> pageResult(Integer page, Integer pageSize, String name) {
        //1.分页构造器对象
        Page<Dish> pageInfo = new Page(page, pageSize);

        Page<DishDto> dishDtoPage = new Page<DishDto>();
        //2.判断是否根据name查询
        query().like(StringUtils.isNotBlank(name), "name", name)
                .orderByDesc("update_time").page(pageInfo);
        //对象拷贝 将pageInfo拷贝到dishPage，除了records属性，因为pageInfo的records属性存储的是dish集合，缺少我们需要的分类名字
        BeanUtils.copyProperties(pageInfo, dishDtoPage, "records");
        //将pageInfo内的records属性存储的dish集合拿出来
        List<Dish> records = pageInfo.getRecords();
        //通过stream流取出集合的每一个dish对象
        List<DishDto> list = records.stream().map((item) -> {
            //先创建一个新的DishDto对象
            DishDto dishDto = new DishDto();
            //继续用拷贝方法，将dish数据拷贝给dishDto,之后dishDto就只差一个categoryName了
            BeanUtils.copyProperties(item, dishDto);
            //从dish对象中取出categoryId，后面用于查询数据库
            Long categoryId = item.getCategoryId(); //分类id
            //通过categoryId查询出category对象
            Category category = categoryService.getById(categoryId);
            //从category对象取出name
            String categoryName = category.getName();
            //然后将categoryName赋值给dishDto的categoryName
            dishDto.setCategoryName(categoryName);
            //这个时候我们前端需要展示的所有数据都准备好了
            return dishDto;
        }).collect(Collectors.toList()); //转为DishDto类型的集合
        //这个时候之前dishDtoPage缺少的records数据就可以添加进来了
        dishDtoPage.setRecords(list);
        //这里就可以返回dishDtoPage了
        return Result.success(dishDtoPage);
    }

    /**
     * 新增菜品 ,同时插入口味数据
     *
     * @param dish
     * @return
     */
    @Override
    @Transactional
    public Result<String> saveDish(DishDto dishDto) {
        //1.新增菜品基本信息到dish表中
        save(dishDto);

        Long dishId = dishDto.getId();//菜品id
        //菜品口味
        // 因为前端返回的flavors对象中没有dish_id，所以需要循环将dishId传入每个对象中
        List<DishFlavor> flavors = dishDto.getFlavors();
        for (DishFlavor flavor : flavors) {
            flavor.setDishId(dishId);
        }
        //2.同时新增口味到dish_flavor表
        dishFlavorService.saveBatch(dishDto.getFlavors());
        return Result.success("添加成功!");
    }

    /**
     * 回显菜品信息
     *
     * @param id
     * @return
     */
    @Override
    public Result<DishDto> selectById(Long id) {
        //1.创建一个dishDto对象
        DishDto dishDto = new DishDto();
        //2.根据id查询菜品信息
        Dish dish = getById(id);
        //2.1 将dish拷贝给dishDto
        BeanUtils.copyProperties(dish, dishDto);
        //3.根据dish拿到categoryId
        Long categoryId = dish.getCategoryId();
        //4.根据categoryId去查询categoryName
        String categoryName = categoryService.getById(categoryId).getName();
        //5.通过id查询dish_flaor表
        List<DishFlavor> dishFlavors = dishFlavorService.query().eq("dish_id", id).list();
        //6.将name和dishfalor封装到dishDto
        dishDto.setCategoryName(categoryName);
        dishDto.setFlavors(dishFlavors);
        //返回
        return Result.success(dishDto);
    }

    /**
     * 修改菜品信息
     *
     * @param dishDto
     * @return
     */
    @Override
    @Transactional
    public Result<String> update(DishDto dishDto) {
        //1.修改dish表基本数据
        this.updateById(dishDto);
        //2.取出dishDto的flavor,修改对应的dish_flavor表数据
        //这里要及其注意，刚开始以为直接覆盖就行了，发现新增或删除操作，就会出问问题
        //所以这里最好的办法是先将口味表对应的数据清空，在新增穿过来修改后的数据
        List<DishFlavor> flavors = dishDto.getFlavors();
        //select * from dish_flavor where dish_id = ?
        List<DishFlavor> dishFlavors = dishFlavorService.query().eq("dish_id", dishDto.getId()).list();
        //delete from dish_flavor where id = ?
        dishFlavorService.removeBatchByIds(dishFlavors);

        // 因为前端返回的flavors对象中没有dish_id，所以需要循环将dishId传入每个对象中
        for (DishFlavor flavor : flavors) {
            flavor.setDishId(dishDto.getId());
        }
        dishFlavorService.saveBatch(flavors);
        return Result.success("修改成功！");
    }


    /**
     *  删除单个菜品
     * @param id
     * @return
     */
    @Override
    public Result<String> deleteById(List<Long> id) {
        //1.先删除菜品对应的口味信息
        // select * from dish_flavor where dish_id in (?,....)
        List<DishFlavor> dishFlavors = dishFlavorService.query().in("dish_id", id).list();
        dishFlavorService.removeBatchByIds(dishFlavors);
        //2.再删除dish表中的基本数据
        //delete from dish where id in (?,?...)
        this.removeBatchByIds(id);
        return Result.success("删除成功！");
    }

    /**
     * 修改状态码 （0：禁售 1：启售）
     * @param status
     * @param id
     * @return
     */
    @Override
    public Result<String> updateStatus(Integer status, List<Long> id) {
        List<Dish> dishs = query().in("id", id).list();
        for (Dish dish : dishs) {
            dish.setStatus(status);
        }
        updateBatchById(dishs);
        return Result.success("操作成功！");
    }

    /**
     *  套餐管理模块下的新增菜品回显功能
     * @param id
     * @return
     */
    @Override
    public Result<List<DishDto>> list(Dish dish) {
        List<Dish> dishList = this.query()
                .eq("category_id",dish.getCategoryId())
                .eq("status", 1)
                .orderByAsc("sort")
                .orderByDesc("update_time")
                .list();
        List<DishDto> dishDtoList = dishList.stream().map((item) -> {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item, dishDto);
            Long categoryId = item.getCategoryId();
            Category category = categoryService.getById(categoryId);

            if (category != null) {
                String categoryName = category.getName();
                dishDto.setCategoryName(categoryName);
            }

            Long dishId = item.getId();
            List<DishFlavor> dishFlavors = dishFlavorService.query().eq("dish_id", dishId).list();

            dishDto.setFlavors(dishFlavors);
            return dishDto;
        }).collect(Collectors.toList());

        return Result.success(dishDtoList);
    }
}




